package com.tjbank.cssys.config.shiro.stateless.realms;

import com.tjbank.cssys.config.shiro.ShiroTokenCacheManager;
import com.tjbank.cssys.config.shiro.stateless.token.StatelessToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Copyright © 天阳宏业科技股份有限公司 - All Rights Reserved
 *
 * 无状态请求一个需要权限的url过程：
 * 
 * 1. StatelessAuthcFilter isAccessAllowed
 * 
 * 2. StatelessAuthcFilter onAccessDenied
 * 
 * 3. StatelessRealm doGetAuthenticationInfo 登录
 * 
 * 4. StatelessRealm doGetAuthorizationInfo 授权 （授权未通过）
 * 
 * 5.AuthRealm doGetAuthorizationInfo
 * 
 * @author: <a href="mailto:guzheng01@tansun.com.cn>Joey Gu</a>
 * 
 * @date: 2020-06-08 20:09
 **/
@Slf4j
public class StatelessTokenRealm extends AuthorizingRealm {

    @Autowired
    private ShiroTokenCacheManager shiroTokenCacheManager;

    public StatelessTokenRealm() {
        super();
        setName("StatelessRealm");
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        // 仅支持StatelessToken类型的Token
        return token instanceof StatelessToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        if (log.isDebugEnabled()) {
//            log.debug(">>>无状态 授权验证");
//        }
//        // 根据用户名查找角色
//        // 获取当前登录输入的用户名，
//        // 等价于(String) principalCollection.fromRealm(getName()).iterator().next();
//        String userCode = (String) super.getAvailablePrincipal(principals);
//
//        // 根据用户名去数据库查询用户信息
//        UserDTO userDTO = userService.getUserByCode(userCode);
//
//        // 添加 权限信息对象info，用来存放查出的用户的所有角色和权限
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//
//        // 根据用户ID查询关联关系表中角色信息集合
//        List<RoleDTO> roleList = userService.queryRoleListByUserId(userDTO.getId());
//        // 添加角色
//        roleList.forEach(role -> info.addRole(role.getRoleName()));
//
//        // 根据角色ID集合查询权限信息集合
//        List<PermissionDTO> permissionList = roleservice.queryPermissionByRoleIds(roleList);
//        permissionList.forEach(p -> info.addStringPermission(p.getPermName()));
//        
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        StatelessToken statelessToken = (StatelessToken) token;
        String loginCode = statelessToken.getLoginCode();
        // 需要在服务器端生成客户端参数消息摘要？
        String tokenStr = statelessToken.getToken();
        if (log.isDebugEnabled()) {

        }
        if (tokenStr == null || !shiroTokenCacheManager.validateOnlineSession(loginCode, tokenStr)) {
            throw new AuthenticationException("User " + loginCode + " authenticate fail in System");
        }
        // 然后进行客户端消息摘要和服务器端消息摘要的匹配
        return new SimpleAuthenticationInfo(loginCode, tokenStr, getName());
    }

}
